package com.google.protobuf.compiler.java;

import java.util.HashMap;
import java.util.Map;

import com.google.protobuf.DescriptorProtos.EnumDescriptorProto;
import com.google.protobuf.DescriptorProtos.EnumValueDescriptorProto;

public class EnumGenerator implements IGenerator {
	private EnumDescriptorProto _descriptor;
	private Map<String, String> _variables = new HashMap<>();

	public EnumGenerator(EnumDescriptorProto descriptor, String packageName, String scope) {
		_descriptor = descriptor;
		_variables.put("class", Util.makeASClassName(scope, descriptor.getName()));
		_variables.put("package", packageName);
	}

	@Override
	public void generate(Printer printer) {
		printer.writeln(_variables, "package #package#;\n\n" + //
				"public enum #class# {");//

		for (EnumValueDescriptorProto field : _descriptor.getValueList()) {
			_variables.put("field_name", field.getName());
			_variables.put("field_value", String.valueOf(field.getNumber()));
			printer.writeln(_variables, "    #field_name#(#class#.#field_name#_VALUE),");
			if (field.getNumber() == 0) {
				_variables.put("default_field_value", field.getName());
			}
		}
		printer.writeln(_variables, "	;");
		printer.writeln();
		// 常量区
		for (EnumValueDescriptorProto field : _descriptor.getValueList()) {
			_variables.put("field_name", field.getName());
			_variables.put("field_value", String.valueOf(field.getNumber()));
			printer.writeln(_variables, "    public static final int #field_name#_VALUE = #field_value#;");
		}
		printer.writeln();
		printer.writeln(_variables, "	private final int value;\n");
		printer.writeln(_variables,
				"    private #class#(final int value) {\n" + //
						"        this.value = value;\n" + //
						"    }\n" + //
						"    \n" + //
						"    public static #class# valueOf(int value) {\n" + //
						"        switch (value) {\n" + ///
						"            default:\n" + ////
						"                return #default_field_value#;");//
		printer.indent();
		for (EnumValueDescriptorProto field : _descriptor.getValueList()) {
			_variables.put("field_name", field.getName());
			_variables.put("field_value", String.valueOf(field.getNumber()));
			printer.writeln(_variables, "        case #field_value#:\n" + //
					"            return #field_name#;");//
		}
		printer.outdent();
		printer.writeln(_variables,
				"        }\n" + //
						"    }\n" + //
						"    \n" + //
						"    public int getValue() {\n" + //
						"        return value;\n" + //
						"    }\n" + //
						"}");
	}
}
